package com.anxin.act.task.service;

import com.alibaba.fastjson.JSONArray;
import com.anxin.act.task.dao.WfActHiTaskDao;
import com.anxin.act.task.dao.WfActRuTaskDao;
import com.anxin.act.task.dao.WfCcRecordDao;
import com.anxin.act.task.entity.ViewHiTask;
import com.anxin.act.task.entity.WfActHiTask;
import com.anxin.act.task.entity.WfActRuTask;
import com.anxin.act.task.vo.TaskVo;
import com.anxin.act.utils.ActTaskUtils;
import com.anxin.act.utils.ActUtils;
import com.anxin.common.utils.sys.UserUtils;
import com.anxin.framework.web.service.BaseService;
import com.anxin.sys.file.dao.FileBaseDao;
import com.anxin.sys.system.entity.SysUser;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * 加签任务Service业务层处理
 *
 * @author jbs
 * @date 2021-10-22
 */
@Service
public class WfActRuTaskService extends BaseService<WfActRuTaskDao, WfActRuTask>{

    @Autowired
    private WfActRuTaskDao wfActRuTaskDao;
    @Autowired
    private WfActHiTaskDao wfActHiTaskDao;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private FileBaseDao fileBaseDao;
    @Autowired
    private WfCcRecordDao wfCcRecordDao;
    @Autowired
    private WfActTaskVariableService wfActTaskVariableService;


    /**
     * 提交任务
     * @param taskId 待办ID
     * @param var 变量
     */
    @Transactional(readOnly = false)
    public void complete(String taskId, Map<String, Object> var){
        // 删除待办
        wfActRuTaskDao.deleteById(taskId);
        // 更新已办
        wfActHiTaskDao.complete(new WfActHiTask(taskId));
        // 恢复任务
        this.restoreTask(taskId,var);
    }

    /**
     * 撤回时删除任务
     * @param viewHiTask
     */
    @Transactional(readOnly = false)
    public void delByTaskId(ViewHiTask viewHiTask){
        wfActRuTaskDao.delByTaskId(viewHiTask);
    }

    /**
     * 撤回时删除任务，包括附件，抄送等信息
     * @param viewHiTask
     */
    @Transactional(readOnly = false)
    public void delAllByTaskId(ViewHiTask viewHiTask){
        WfActRuTask wfActRuTask = new WfActRuTask();
        wfActRuTask.setActTaskId(viewHiTask.getTaskId());

        List<WfActRuTask> taskList = wfActRuTaskDao.findList(wfActRuTask);
        for (WfActRuTask actRuTask : taskList) {
            // 删除附件
            fileBaseDao.deleteFile("act_approval",actRuTask.getId());
            // 删除抄送记录
            wfCcRecordDao.delByTaskId(actRuTask.getId());
        }
        wfActRuTaskDao.delByTaskId(viewHiTask);
    }


    /**
     * 撤回时根据SourceId删除任务
     * @param sourceId
     */
    @Transactional(readOnly = false)
    public void delBySourceId(String sourceId){
        List<WfActRuTask> wfActRuTaskList = wfActRuTaskDao.findBySourceId(sourceId);
        for (WfActRuTask wfActRuTask : wfActRuTaskList) {
            this.delBySourceId(wfActRuTask.getId());
            wfActRuTaskDao.deleteById(wfActRuTask.getId());
        }
    }


    /**
     * 任务完成后恢复之前的任务
     * @param taskId 任务ID
     * @param taskId 变量
     */
    public void restoreTask(String taskId, Map<String, Object> var){
        WfActHiTask wfActHiTask = wfActHiTaskDao.getById(taskId);
        List<WfActRuTask> wfActRuTaskList = this.findByActSourceId(wfActHiTask.getSourceId());

        // 如果本次加签任务仅省这个一个任务，则恢复加签任务
        if (wfActRuTaskList.size() == 0){

            // 前加签任务
            if ("addBefore".equals(wfActHiTask.getType())){
                // 恢复任务
                this.restoreTask(wfActHiTask);
            }else if ("addAfter".equals(wfActHiTask.getType()) || "entrust".equals(wfActHiTask.getType()) || "freeFlow".equals(wfActHiTask.getType())){ // 后加签
                this.completeAfterTask(wfActHiTask,var);
            }

        }

    }

    /**
     * 后加签审批完成后提交任务
     * @param wfActHiTask
     * @param var 流程变量
     */
    public void completeAfterTask(WfActHiTask wfActHiTask, Map<String, Object> var){
        if ("actTask".equals(wfActHiTask.getSourceType())){
//            Task task = taskService.createTaskQuery().taskId(wfActHiTask.getActTaskId()).singleResult();
//            // 查询出之前的审批人
//            Object actPreviousApprover = runtimeService.getVariable(task.getExecutionId(), "actPreviousApprover");
//            if (actPreviousApprover != null){
//                taskService.setAssignee(wfActHiTask.getActTaskId(), actPreviousApprover.toString());
//            }
            taskService.complete(wfActHiTask.getActTaskId(),var);
        }else {
            this.complete(wfActHiTask.getSourceId(),var);
        }
    }

    /**
     * 恢复任务
     * @param wfActHiTask
     */
    public void restoreTask(WfActHiTask wfActHiTask){
        if ("actTask".equals(wfActHiTask.getSourceType())){ // Activiti任务
            this.restoreActTask(wfActHiTask.getSourceId());
        }else { // 加签任务
            this.restoreAddTask(wfActHiTask);
        }
    }


    /**
     * 恢复activiti 任务
     * @param taskId 待办任务的ID
     */
    public void restoreActTask(String taskId){
        Task task = ActTaskUtils.getTask(taskId);

        String actPreviousApprover = runtimeService.getVariableLocal(task.getExecutionId(), "actPreviousApprover").toString();
        // 恢复审批人
        taskService.setAssignee(task.getId(),actPreviousApprover);
        // 删除之前设置的流程变量
        runtimeService.removeVariableLocal(task.getExecutionId(),"actPreviousApprover");
        // 修改任务启动时间
        ActTaskUtils.updateTaskStartTime(taskId);

    }

    /**
     * 恢复加签任务
     * @param wfActHiTask 加签任务
     */
    public void restoreAddTask(WfActHiTask wfActHiTask){
        WfActHiTask hiTask = wfActHiTaskDao.getById(wfActHiTask.getSourceId());
        wfActRuTaskDao.restoreTask(hiTask.getId());
        wfActHiTaskDao.restoreTask(hiTask.getId());
    }

    /**
     * 根据任务ID查询
     * @param taskId
     * @return
     */
    public List<WfActRuTask> findByActTaskId(String taskId){
        WfActRuTask wfActRuTask = new WfActRuTask();
        wfActRuTask.setActTaskId(taskId);
        return wfActRuTaskDao.findList(wfActRuTask);
    }

    /**
     * 根据任务 sourceId 查询
     * @param sourceId
     * @return
     */
    public List<WfActRuTask> findByActSourceId(String sourceId){
        WfActRuTask wfActRuTask = new WfActRuTask();
        wfActRuTask.setSourceId(sourceId);
        return wfActRuTaskDao.findList(wfActRuTask);
    }

    /**
     * 执行加签操作
     * @param taskVo 加签用户集合
     */
    @Transactional(readOnly = false)
    public void addTask(TaskVo taskVo){
        this.addTask(taskVo,null);
    }

    /**
     * 执行加签操作
     * @param taskVo 加签用户集合
     * @param taskVo 流程变量
     */
    @Transactional(readOnly = false)
    public void addTask(TaskVo taskVo, Map<String,String> var){

        WfActRuTask wfActRuTask = new WfActRuTask(taskVo);

        JSONArray addUserArray = taskVo.getAddUser();
        for (int i = 0; i < addUserArray.size(); i++) {
            String userId = addUserArray.getString(i);
            SysUser user = UserUtils.getUser(userId);
            if (user != null){
                wfActRuTask.setId(null);
                wfActRuTask.setAssignee(user.getUserName());
                super.save(wfActRuTask);
                // 保存历史任务
                wfActHiTaskDao.insertByRuTask(wfActRuTask);

                // 保存流程变量
                if (var != null){
                    wfActTaskVariableService.save(wfActRuTask.getActId(),wfActRuTask.getId(),var);
                }
            }

        }

    }



    /**
     * 查询加签任务
     *
     * @param id 加签任务ID
     * @return 加签任务
     */
    public WfActRuTask getById(String id){
        return wfActRuTaskDao.getById(id);
    }

    /**
     * 查询加签任务列表
     *
     * @param wfActRuTask 加签任务
     * @return 加签任务
     */
    public List<WfActRuTask> findList(WfActRuTask wfActRuTask){
        return wfActRuTaskDao.findList(wfActRuTask);
    }



    /**
     * 保存加签任务
     *
     * @param wfActRuTask 加签任务
     * @return 结果
     */
    public int save(WfActRuTask wfActRuTask){
        return super.save(wfActRuTask);
    }


    /**
     * 删除加签任务信息
     *
     * @param id 加签任务ID
     * @return 结果
     */
    public int deleteById(String id){
        return wfActRuTaskDao.deleteById(id);
    }

    /**
     * 修改流程审批人
     * @param id 任务ID
     * @param assignee 新的审批人
     */
    public void updateAssignee(String id, String assignee){
        wfActRuTaskDao.updateAssignee(id,assignee);
    }
}
